package com.zl.test.util;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

public class RsaUtil {

    private static String ALGORITHM = "RSA";
    private static String PUBLIC_KEY_BASE64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFHIx1LmZQEzsuHswp6MxYPKLkr9Qu3RibLJ41cYe2hlrBGr2hWEBK3rP4+CX8cWAhx2okftBep5TkhwIB3/sWYwDotOG3BuwJlNW8ovgROLMb4EW1OwZJAiOVK103GlqNK3t1b2uOI4dlX36pc8hmOLIb3Ym/OJDxT39Iuus+xQIDAQAB";
    private static String PRIVATE_KEY_BASE64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIUcjHUuZlATOy4ezCnozFg8ouSv1C7dGJssnjVxh7aGWsEavaFYQEres/j4JfxxYCHHaiR+0F6nlOSHAgHf+xZjAOi04bcG7AmU1byi+BE4sxvgRbU7BkkCI5UrXTcaWo0re3Vva44jh2VffqlzyGY4shvdib84kPFPf0i66z7FAgMBAAECgYBPcax6u4igvfmSGxtq3+AlwXrO1gnjNl3bLxP1fZ6r1yAPJDCNPSiSBryPGTtCoT/oqSW2RmGCPK5mfhU6nT0zSs3sawMa6VYUb1IOkFJatrqaqHbfF4GePGT5z5EtlyTm/dBNc2Qx2SsuOb9u5Hvfy58DwnizMK4vYTntaO51wQJBAOlrqbA6HP31AaCmFkdVdCFCnAlDfoSdiq0hyoRT9rJZyH47NIaUWkAJzfCzIUQAZbCXnMwdx0mKsfkG+pTKdT0CQQCR/N8JXsUPC5jMSOat8FJkrLDhgoY0jWJIk6NudHa23d6dyIZQfTbdPW24344usJUUYhOC6JZCtmX7rsFZD9gpAkADV0EkfpBvqhQN4pKrDrQMzdFB6K9k4oRbmgI2BqWfQ920wNAtpO3twLYr3cR6Hq9V6bWazkpN6ShG8iyf+I3ZAkBgZvitilxclA7hj55s7A6slnDzaarP1zE4te2tSdD+7sJLtRgk3Jq3PBJRi6arZEX9wMobnxVilmn/6iWZd2IJAkEAy6PfFQCNv4Dvc0zHbBa1pBvY1ocPWOOSglUsIiEXY8Z3ZNIvI4kBXfszGQJ5Il2l4EpIoI5dzoHmT9a0N+qT1A==";
 
    private static KeyFactory keyFactory;
    private static Key publicKey;
    private static Key privateKey;
    
    static {
    	init();
    }
    
    /**
     * 初始化rsa密钥对
     */
    private static void init() {
    	try {
			keyFactory = KeyFactory.getInstance(ALGORITHM);
			initPubKey();
			initPriKey();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
    }
    
    /**
     * 初始化公钥
     * @throws InvalidKeySpecException
     */
    private static void initPubKey() throws InvalidKeySpecException {
    	
		byte[] keyBytes = Base64.getDecoder().decode(PUBLIC_KEY_BASE64);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		publicKey = keyFactory.generatePublic(x509KeySpec);
    }
    
    /**
     * 初始化私钥
     * @throws InvalidKeySpecException
     */
    private static void initPriKey() throws InvalidKeySpecException {
    	
		byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY_BASE64);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    }
    
    /**
	 * 用公钥加密
	 * @throws Exception
	 */
	private static byte[] encryptByPublicKey(byte[] data) throws Exception {
		
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}
	
	/**
	 * 用私钥解密
	 * @throws Exception
	 */
	private static byte[] decryptByPrivateKey(byte[] data) throws Exception {
		
		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}
	
    /**
     * 对原文加密为密文
     * @param source	原文,最长支持117个字节
     * @return
     * @throws Exception
     */
    public static String encrypt(String source) throws Exception {
        
    	byte[] enc=encryptByPublicKey(source.getBytes("utf-8"));
    	return Base64.getEncoder().encodeToString(enc);
    }
 
    /**
     * 解密密文
     * @param ciphertext
     * @return
     * @throws Exception
     */
    public static String decrypt(String ciphertext) throws Exception {
    	
    	byte[] dec=Base64.getDecoder().decode(ciphertext);
    	byte[] buf=decryptByPrivateKey(dec);
    	return new String(buf,"utf-8");
    }
    
}